/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.sales.hancadpe.client.presenter;

import br.com.sales.generics.client.HanAbstractPresenter;
import br.com.sales.generics.client.components.autocomplete.widget.Autocomplete;
import br.com.sales.generics.client.components.mask.MaskEditHandler;
import br.com.sales.generics.client.components.mask.MaskTextFieldWidget;
import br.com.sales.generics.client.components.scroll.HScroll;
import br.com.sales.generics.client.components.timepicker.HDateTimePicker;
import br.com.sales.generics.client.nametoken.NameTokens;
import br.com.sales.generics.client.presenter.events.EditRecordEvent;
import br.com.sales.generics.client.presenter.events.EditRecordHandler;
import br.com.sales.generics.client.request.HannaRequestCallback;
import br.com.sales.hancadpe.client.presenter.grid.HanCadPEGrid;
import br.com.sales.hancadpe.client.presenter.values.ControlValues;
import br.com.sales.hancadpe.client.service.HanCadPEService;
import com.google.gwt.core.client.JsonUtils;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.Response;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.HasUiHandlers;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ContentSlot;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.gwtplatform.mvp.client.proxy.RevealContentHandler;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 *
 * @author v
 */
public class HanCadPEPresenter
        extends HanAbstractPresenter<HanCadPEPresenter.Display, HanCadPEPresenter.MyProxy>
        implements HanCadPEUiHanlder, EditRecordHandler {

    @ContentSlot
    public static final GwtEvent.Type<RevealContentHandler<?>> HANCADPE_SLOT_TYPE = new GwtEvent.Type<>();
    private static final Double EIGHTEEN_YEARS = 6574.5;
    private static final String CLIENT = "2";
    private boolean isEditing;
    @Inject
    private ControlValues controlValues;
    @Inject
    private HanCadPEGrid grid;
    private long sequenceEditing = 0;
    @Inject
    private HanCadPEService service;
    private final HTMLPanel panelGrid = new HTMLPanel("");
    private static final Map CACHED_PERSON = new LinkedHashMap();
    private boolean isValid = false;

    @Inject
    public HanCadPEPresenter(EventBus eventBus, HanCadPEPresenter.Display view, HanCadPEPresenter.MyProxy proxy) {
        super(eventBus, view, proxy);
        getView().setUiHandlers(this);
    }

    @Override
    protected void onBind() {
        super.onBind();
        getView().build();
        getEventBus().addHandler(EditRecordEvent.TYPE, this);
    }

    @Override
    protected void onReveal() {
        getView().setEnabled(isEditing);
        panelGrid.setVisible(false);
        panelGrid.add(grid);
        panelGrid.add(getView().getLoadingMessage());
        getView().getFilterContainer().setVisible(false);
        getView().setInSlot(HANCADPE_SLOT_TYPE, getView().getDetailPanel());
    }

    @Override
    public void onClickNew(ClickEvent event) {
        if (!isEditing) {
            setValuesRecord(true);
        } else {
            if (Window.confirm("Deseja cancelar a edição atual?")) {
                setValuesRecord(true);
            }
        }
    }

    private void setValuesRecord(boolean newRecord) {
        isEditing = true;
        getView().getFilterContainer().setVisible(false);
        getView().setEnabled(isEditing);
        getView().controlVisibleButton(isEditing);
        if (newRecord) {
            controlValues.clearFields(getView());
            setDefaultValue();
        }
        getView().getNmPersonEdit().setFocus(true);
        if (panelGrid.isVisible()) {
            getView().setInSlot(HANCADPE_SLOT_TYPE, getView().getDetailPanel());
            panelGrid.setVisible(false);
        }
        getView().changeCpfEdit();
    }

    private void setDefaultValue() {
        DateTimeFormat format = DateTimeFormat.getFormat("dd/MM/yyyy HH:mm:ss");
        getView().getDateEdit().setText(format.format(new Date(System.currentTimeMillis())));
        getView().getIsTipoPessoa().setValue(true);
    }

    @Override
    public void edit(JSONObject record) {
        sequenceEditing = Long.parseLong(toString(record.get("SEQ")));
        getView().getSenhaEdit().setText(toString(record.get("DS_SENHA")));
        getView().getUsuarioEdit().setValue(toString(record.get("NM_USUARIO")));
        getView().getStateComplete().setValue(toString(record.get("DS_ESTADO")), toString(record.get("NR_SEQ_ESTADO")));
        getView().getCityComplete().setValue(toString(record.get("DS_CIDADE")), toString(record.get("NR_SEQ_CIDADE")));
        getView().getCountryComplete().setValue(toString(record.get("DS_PAIS")), toString(record.get("NR_SEQ_PAIS")));
        getView().getNrCelularEdit().setValue(toString(record.get("NR_CELULAR")));
        getView().getNrTelefoneEdit().setValue(toString(record.get("NR_TELEFONE")));
        getView().getEnderecoEdit().setValue(toString(record.get("DS_ENDERECO")));
        getView().getRgEdit().setValue(toString(record.get("CD_RG")));
        getView().getCpfEdit().setValue(toString(record.get("CD_CPF")));
        getView().getDateNascimentoEdit().setValue(toString(record.get("DT_NASCIMENTO")));
        getView().getIsTipoPessoa().setValue("S".equals(toString(record.get("IE_TIPO_PESSOA"))));
        getView().getNmPersonEdit().setText(toString(record.get("NM_PESSOA_FISICA")));
        getView().getDateEdit().setText(toString(record.get("DT_REGISTRO")));
        getView().getUsuarioTipo().setItemSelected(Integer.parseInt(toString(record.get("IE_TIPO_USUARIO"))), true);

        setValuesRecord(false);

    }

    private String toString(JSONValue value) {
        if (value == null) {
            return "";
        }
        if (value instanceof JSONString) {
            return value.isString().stringValue();
        } else if (value instanceof JSONNumber) {
            return value.isNumber().toString();
        }
        return "";
    }

    @Override
    public void onClickCancel(ClickEvent event) {
        if (Window.confirm("Deseja cancelar?")) {
            controlValues.clearFields(getView());
            isEditing = false;
            getView().setEnabled(isEditing);
            getView().controlVisibleButton(isEditing);
            grid.setIsEditing(false);
            getView().isMandatory(isEditing);
        }
    }

    @Override
    public void onClickSave(ClickEvent event) {
        if (getView().isMandatory(isEditing)) {
            return;
        } else if (!getView().getCountryComplete().isValidValue()
                || !getView().getCityComplete().isValidValue()
                || !getView().getStateComplete().isValidValue()) {
            Window.alert("Existem campos inválidos!\nFavor verificar.");
            return;
        } else if (!isValid && !grid.isEditing()) {
            Window.alert("Pessoa já cadastrada no sistema!\nFavor Verificar o (CPF/RG).");
            return;
        }
        if (!validate()) {
            return;
        }
        final Map params = new LinkedHashMap();
        params.put("SEQ", sequenceEditing);
        params.put("DT_REGISTRO", getView().getDateEdit().getText());
        params.put("NM_PESSOA_FISICA", getView().getNmPersonEdit().getText());
        params.put("IE_TIPO_PESSOA", getView().getIsTipoPessoa().getValue() ? "S" : "N");
        params.put("DT_NASCIMENTO", getView().getDateNascimentoEdit().getValueAsString());
        params.put("CD_CPF", getView().getCpfEdit().getValue());
        params.put("CD_RG", getView().getRgEdit().getValue());
        params.put("DS_ENDERECO", getView().getEnderecoEdit().getValue());
        params.put("NR_TELEFONE", getView().getNrTelefoneEdit().getValue());
        params.put("NR_CELULAR", getView().getNrCelularEdit().getValue());
        params.put("NR_SEQ_PAIS", getView().getCountryComplete().getValue());
        params.put("NR_SEQ_ESTADO", getView().getStateComplete().getValue());
        params.put("NR_SEQ_CIDADE", getView().getCityComplete().getValue());
        params.put("NM_USUARIO", getView().getUsuarioEdit().getText());
        params.put("DS_SENHA", getView().getSenhaEdit().getText());
        params.put("IE_TIPO_USUARIO", getView().getUsuarioTipo().getValue(getView().getUsuarioTipo().getSelectedIndex()));

        service.insertPerson(params, new HannaRequestCallback() {

            @Override
            public void onResponseReceived(Request request, Response response) {
                JSONObject record = new JSONObject(JsonUtils.safeEval(response.getText()));
                isEditing = false;
                getView().setEnabled(isEditing);
                getView().controlVisibleButton(isEditing);
                controlValues.clearFields(getView());
                sequenceEditing = 0;
                grid.addValueTogrid(record);
                grid.setIsEditing(false);
            }
        });
    }

    @Override
    public void validateCPF() {
        if (CACHED_PERSON.containsKey(getView().getCpfEdit().getValue())
                || CACHED_PERSON.containsValue(getView().getRgEdit().getText())) {
            isValid = false;
        } else {
            Map itens = new LinkedHashMap();
            itens.put("CPF", getView().getCpfEdit().getValue());
            itens.put("RG", getView().getRgEdit().getText());

            service.validateDocument(itens, new HannaRequestCallback() {

                @Override
                public void onResponseReceived(Request request, Response response) {
                    if (Boolean.valueOf(response.getText().trim())) {
                        CACHED_PERSON.put(getView().getCpfEdit().getValue(), getView().getRgEdit().getText());
                        isValid = false;
                    } else {
                        isValid = true;
                    }
                }
            });
        }
    }

    private boolean validate() {
        if (getView().getIsTipoPessoa().getValue()) {
            DateTimeFormat format = DateTimeFormat.getFormat("dd/MM/yyyy");
            Date dateEighteenYears = format.parse(getView().getDateNascimentoEdit().getValueAsString());
            Date now = new Date(System.currentTimeMillis());

            if (now.before(dateEighteenYears)) {
                Window.alert("A data de nascimento não pode ser maior que a data atual!");
                getView().getDateNascimentoEdit().setFocus(true);
                return false;
            }
            if (CLIENT.equals(getView().getUsuarioTipo().getValue(getView().getUsuarioTipo().getSelectedIndex()))) {
                if ((CalendarUtil.getDaysBetween(dateEighteenYears, now)) <= EIGHTEEN_YEARS) {
                    Window.alert("Somente pessoas acima de 18 anos podem se cadastrar!");
                    getView().getDateNascimentoEdit().setFocus(true);
                    return false;
                }
            }
        }

        return true;
    }

    @Override
    public void onClickGridDetail(ClickEvent event) {
        if (!panelGrid.isVisible()) {
            getView().setInSlot(HANCADPE_SLOT_TYPE, panelGrid.asWidget());
            panelGrid.setVisible(true);
            getView().getFilterContainer().setVisible(true);
            grid.refresh(getDataFilter());
        } else {
            getView().setInSlot(HANCADPE_SLOT_TYPE, getView().getDetailPanel().asWidget());
            panelGrid.setVisible(false);
            getView().getFilterContainer().setVisible(false);
        }
    }

    @Override
    public void onClickRefreshBtn(ClickEvent event) {
        grid.refresh(getDataFilter());
    }

    private Map getDataFilter() {
        Map param = new HashMap();
        param.put("NM_PESSOA", getView().getFilterName().getValue());
        param.put("DT_INICIO", getView().getInitialDate().getValueAsString() + " 00:00:00");
        param.put("DT_FIM", getView().getFinalDate().getValueAsString() + " 23:59:59");

        return param;
    }

    @ProxyStandard
    @NameToken(NameTokens.REGISTERPERSON)
    public interface MyProxy extends ProxyPlace<HanCadPEPresenter> {
    }

    public interface Display extends View, HasUiHandlers<HanCadPEUiHanlder> {

        void build();

        void setEnabled(boolean isNewrecord);

        void controlVisibleButton(boolean isNewrecord);

        boolean isMandatory(Boolean isEditing);

        TextBox getNmPersonEdit();

        Image getLoadingMessage();

        HScroll getMainContentScrollPanel();

        FlowPanel getMainContentPanel();

        TextBox getDateEdit();

        MaskEditHandler getCpfEdit();

        MaskTextFieldWidget getRgEdit();

        MaskTextFieldWidget getNrTelefoneEdit();

        MaskTextFieldWidget getNrCelularEdit();

        VerticalPanel getPaisEdit();

        TextBox getUsuarioEdit();

        TextBox getSenhaEdit();

        HTMLPanel getDetailPanel();

        Autocomplete getCountryComplete();

        Autocomplete getCityComplete();

        Autocomplete getStateComplete();

        CheckBox getIsTipoPessoa();

        HDateTimePicker getDateNascimentoEdit();

        TextBox getEnderecoEdit();

        ListBox getUsuarioTipo();

        HDateTimePicker getInitialDate();

        HDateTimePicker getFinalDate();

        TextBox getFilterName();

        HTMLPanel getFilterContainer();

        void changeCpfEdit();
    }
}
